package com.example.eurekaclient_consumer1.controller;

import com.example.eurekaclient_consumer1.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * ClassName:ConsumerController
 * Package:com.bjpowernode.springcloud.controller
 * Description: 描述信息
 *
 * @date:2021/12/17 16:19
 * @author:动力节点
 */
@Slf4j
@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    /*
        RestTemplate：Spring封装的远程调用的模板对象，发送http的restful api请求操作
            post、delete、put、get：不同的请求方式，代表不同的增删改查
            方法名称
                getForEntity(String url,Class responseType)：返回值ResponseEntity<T>
                getForEntity(String url,Class responseType,Object... objs)：返回值ResponseEntity<T>
                getForEntity(String url,Class responseType,Map params)：返回值ResponseEntity<T>
                    参数列表：
                        参数1，url请求地址
                        参数2，响应的字节码类型
                        参数3，封装的参数，可以用可变参数封装，也可以通过Map集合的键值对进行封装
                    返回值：ResponseEntity
                        获取提供者返回的结果
                        获取提供者返回的响应头
                        获取提供者返回的响应状态码
                        获取提供者返回的响应状态码对应的值

                getForObject(String url,Class responseType)：返回值<T>
                getForObject(String url,Class responseType,Object... objs)：返回值<T>
                getForObject(String url,Class responseType,Map params)：返回值<T>
                    参数列表：
                        参数1，url请求地址
                        参数2，响应的字节码类型
                        参数3，封装的参数，可以用可变参数封装，也可以通过Map集合的键值对进行封装
                    返回值：T
                        提供者返回的具体数据

                postForEntity(String url,Object request,Class responseType)：返回值ResponseEntity<T>
                postForEntity(String url,Object request,Class responseType,Object... objs)：返回值ResponseEntity<T>
                postForEntity(String url,Object request,Class responseType,Map params)：返回值ResponseEntity<T>
                    参数列表：
                        参数1，url请求地址
                        参数2，封装到请求体中的数据
                        参数3，响应的字节码类型
                        参数4，封装的参数，可以用可变参数封装，也可以通过Map集合的键值对进行封装
                    返回值：ResponseEntity
                        获取提供者返回的结果
                        获取提供者返回的响应头
                        获取提供者返回的响应状态码
                        获取提供者返回的响应状态码对应的值
                postForObject：返回值<T>
                postForObject(String url,Object request,Class responseType)：返回值<T>
                postForObject(String url,Object request,Class responseType,Object... objs)：返回值<T>
                postForObject(String url,Object request,Class responseType,Map params)：返回值<T>
                    参数列表：
                        参数1，url请求地址
                        参数2，封装到请求体中的数据
                        参数3，响应的字节码类型
                        参数4，封装的参数，可以用可变参数封装，也可以通过Map集合的键值对进行封装
                    返回值：T
                        提供者返回的具体数据

                put(String url,Object request,Class responseType)：返回值void，如果进行修改，想要获取提供者的返回值，请使用post方式
                put(String url,Object request,Object... objs)：返回值void，如果进行修改，想要获取提供者的返回值，请使用post方式
                put(String url,Object request,Map params)：返回值void，如果进行修改，想要获取提供者的返回值，请使用post方式
                    参数列表：
                        参数1，url请求地址
                        参数2，封装到请求体中的数据
                        参数3，封装的参数，可以用可变参数封装，也可以通过Map集合的键值对进行封装

                delete(String url)：返回值void，如果进行删除，想要获取提供者的返回值，请使用get方式
                delete(String url,Object... objs)：返回值void，如果进行删除，想要获取提供者的返回值，请使用get方式
                delete(String url,Map params)：返回值void，如果进行删除，想要获取提供者的返回值，请使用get方式
                    参数列表：
                        参数1，url请求地址
                        参数2，封装的参数，可以用可变参数封装，也可以通过Map集合的键值对进行封装
            负载均衡调用
                将url地址中的ip+端口，改为微服务的名称，进行远程调用
                    UnknownHostException: EUREKA-CLIENT-PROVIDER
                    EUREKA-CLIENT-PROVIDER代表：7001、7002两个微服务
                在RestTemplate初始化的地方，添加一个负载均衡的注解，@LoadBalanced
                添加了该注解，RestTemplate即可支持负载均衡的远程调用
     */
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 消费者工程，都是get方式接收
     * 通过不同的restTemplate的请求发送，在提供者进行get/post/put/delete方式的接收
     * 方便消费者进行测试，也可以通过postMan进行测试
     *
     * @return
     */
    @GetMapping("/01")
    public R consumer01(HttpServletRequest request) {

        //访问提供者地址
        String url = "http://EUREKA-CLIENT-PROVIDER/provider/01";
//        String url = "http://localhost:7001/provider/01";

        ResponseEntity<R> entity = restTemplate.getForEntity(url, R.class);

        System.out.println("请求头 X-Request-Header :::>>> "+request.getHeader("X-Request-Header"));
        System.out.println("提供者返回的响应头 :::>>> " + entity.getHeaders());
        System.out.println("提供者返回的响应结果 :::>>> " + entity.getBody());
        System.out.println("提供者返回的响应状态码 :::>>> " + entity.getStatusCode());
        System.out.println("提供者返回的响应状态码值 :::>>> " + entity.getStatusCodeValue());

        R r = entity.getBody();

        //为后续的负载均衡做铺垫
        r.put("consumer", 8001);

        return r;
    }


    @GetMapping("/02")
    public R consumer02(HttpServletRequest request, HttpServletResponse response) {

        String url = "http://EUREKA-CLIENT-PROVIDER/provider/02/{id}/{username}";
//        String url = "http://localhost:7001/provider/02/{id}/{username}";

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("id", 111);
        paramsMap.put("username", "张三...");

        System.out.println("请求头 X-Request-Header :::>>> "+request.getHeader("X-Request-Header"));
        System.out.println("请求头 bbb :::>>> "+request.getParameter("bbb"));
        log.info("响应头 ccc : {}",response.getHeader("bbb"));

        R r = restTemplate.getForObject(url, R.class, paramsMap);

        //为后续的负载均衡做铺垫
        r.put("consumer", 8001);

        return r;
    }

    @GetMapping("/03")
    public R consumer03(){
        String url = "http://EUREKA-CLIENT-PROVIDER/provider/03/{id}/{username}?age=18&desc=我是李四";
//        String url = "http://localhost:7001/provider/03/{id}/{username}?age=18&desc=我是李四";

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("id", 222);
        paramsMap.put("username", "李四...");

        R r = restTemplate.getForObject(url, R.class, paramsMap);

        //为后续的负载均衡做铺垫
        r.put("consumer", 8001);

        return r;

    }

    @GetMapping("/04")
    public R consumer04(){

        String url = "http://EUREKA-CLIENT-PROVIDER/provider/04/{id}/{username}?age=22&desc=我是王五";
//        String url = "http://localhost:7001/provider/04/{id}/{username}?age=22&desc=我是王五";

        Map<String,Object> request = new HashMap<>();
        Map<String,Object> paramsMap = new HashMap<>();

        request.put("loginName","wangwu");
        request.put("loginPwd","www.wangwu.com");

        paramsMap.put("id",333);
        paramsMap.put("username","王五");

        ResponseEntity<R> entity = restTemplate.postForEntity(url, request, R.class, paramsMap);

        System.out.println("提供者返回的响应头 :::>>> " + entity.getHeaders());
        System.out.println("提供者返回的响应结果 :::>>> " + entity.getBody());
        System.out.println("提供者返回的响应状态码 :::>>> " + entity.getStatusCode());
        System.out.println("提供者返回的响应状态码值 :::>>> " + entity.getStatusCodeValue());

        R r = entity.getBody();

        //为后续的负载均衡做铺垫
        r.put("consumer", 8001);

        return r;

    }


    @GetMapping("/05")
    public R consumer05(){

        String url = "http://EUREKA-CLIENT-PROVIDER/provider/05/{id}/{username}?age=22&desc=我是赵六";
//        String url = "http://localhost:7001/provider/05/{id}/{username}?age=22&desc=我是赵六";

        Map<String,Object> request = new HashMap<>();
        Map<String,Object> paramsMap = new HashMap<>();

        request.put("loginName","zhaoliu");
        request.put("loginPwd","www.zhaoliu.com");

        paramsMap.put("id",444);
        paramsMap.put("username","赵六");

        R r = restTemplate.postForObject(url, request, R.class, paramsMap);

        //为后续的负载均衡做铺垫
        r.put("consumer", 8001);

        return r;

    }


    @GetMapping("/06")
    public R consumer06(){

        String url = "http://EUREKA-CLIENT-PROVIDER/provider/06/{id}/{username}?age=22&desc=我是田七";
//        String url = "http://localhost:7001/provider/06/{id}/{username}?age=22&desc=我是田七";

        Map<String,Object> request = new HashMap<>();
        Map<String,Object> paramsMap = new HashMap<>();

        request.put("loginName","tianqi");
        request.put("loginPwd","www.tianqi.com");

        paramsMap.put("id",555);
        paramsMap.put("username","田七");

        restTemplate.put(url,request,paramsMap);

        return R.ok();
    }


    @GetMapping("/07")
    public R consumer07(){

        String url = "http://EUREKA-CLIENT-PROVIDER/provider/07/{id}/{username}?age=22&desc=我是王八";
//        String url = "http://localhost:7001/provider/07/{id}/{username}?age=22&desc=我是王八";

        Map<String,Object> paramsMap = new HashMap<>();

        paramsMap.put("id",666);
        paramsMap.put("username","王八");

        restTemplate.delete(url,paramsMap);

        return R.ok();

    }


}
